#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import logging
from typing import Dict, Any, List, Callable
import re
import time
from rule_engine import RuleEngine, Rule

logger = logging.getLogger("悬疑游戏规则引擎")


class ImmersionRule(Rule):
    """沉浸感规则 - 确保回复保持游戏氛围"""
    def __init__(self, description: str = "所有回复应保持游戏氛围，避免出戏内容"):
        super().__init__("immersion", description, priority=95)
        # 常见的出戏词汇和短语
        self.meta_phrases = [
            "系统", "AI", "智能体", "程序", "代码", 
            "游戏机制", "规则", "开发者", "指令"
        ]
    
    def check(self, context: Dict[str, Any]) -> bool:
        """检查响应是否保持游戏沉浸感"""
        self.last_checked = time.time()
        
        # 检查响应文本
        response_text = context.get("response_text", "").lower()
        for phrase in self.meta_phrases:
            if phrase in response_text:
                logger.warning(f"检测到出戏内容: {phrase}")
                return False
        
        return True


class DifficultyBalanceRule(Rule):
    """难度平衡规则 - 确保线索难度适中"""
    def __init__(self, description: str = "线索难度应循序渐进，避免过于简单或困难"):
        super().__init__("difficulty_balance", description, priority=85)
    
    def check(self, context: Dict[str, Any]) -> bool:
        """检查线索难度是否平衡"""
        self.last_checked = time.time()
        
        # 检查当前游戏进度和提供的线索难度
        game_progress = context.get("game_progress", 0.0)
        clue_difficulty = context.get("clue_difficulty", 0.5)
        
        # 线索难度应该与游戏进度大致匹配
        # 游戏初期提供较简单的线索，后期提供更复杂的线索
        expected_difficulty = game_progress * 0.8 + 0.1  # 预期难度范围：0.1-0.9
        
        if abs(clue_difficulty - expected_difficulty) > 0.3:
            logger.warning(f"线索难度不平衡: 当前{clue_difficulty}, 预期{expected_difficulty}")
            return False
        
        return True


class FairPlayRule(Rule):
    """公平游戏规则 - 确保玩家可以通过合理推理找到真相"""
    def __init__(self, description: str = "确保玩家可以通过合理推理找到真相，不设无解谜题"):
        super().__init__("fair_play", description, priority=90)
    
    def check(self, context: Dict[str, Any]) -> bool:
        """检查游戏是否公平"""
        self.last_checked = time.time()
        
        # 检查当前谜题是否有足够的线索支持
        required_clues = context.get("required_clues_for_solution", [])
        available_clues = context.get("available_clues_to_player", [])
        
        # 确保所有必要的线索都会在谜题出现前提供
        if required_clues and not available_clues:
            logger.warning("谜题没有足够的线索支持，可能导致无解")
            return False
        
        # 检查是否有误导性太强的线索
        misleading_clues = context.get("misleading_clues", 0)
        if misleading_clues > len(available_clues) * 0.4:  # 误导性线索不应超过40%
            logger.warning("误导性线索过多，可能导致游戏不公平")
            return False
        
        return True


class AgeAppropriatenessRule(Rule):
    """年龄适宜规则 - 确保内容适合目标年龄段"""
    def __init__(self, description: str = "游戏内容应适合目标年龄段，避免过度恐怖或暴力"):
        super().__init__("age_appropriateness", description, priority=105)  # 较高优先级
        # 不适宜的内容模式
        self.inappropriate_patterns = [
            r'过于血腥|肢解|虐待|酷刑',
            r'极度恐怖|鬼怪附身|血腥暴力',
            r'自杀|自残|自虐',
            r'毒品|吸毒|贩毒',
            r'色情|裸露|性行为'
        ]
    
    def check(self, context: Dict[str, Any]) -> bool:
        """检查内容是否适合目标年龄段"""
        self.last_checked = time.time()
        
        # 获取目标年龄和内容文本
        target_age = context.get("target_age", 16)
        content_text = context.get("content_text", "").lower()
        
        # 对不同年龄段应用不同的审查标准
        if target_age < 12:
            # 儿童内容：严格审查
            for pattern in self.inappropriate_patterns:
                if re.search(pattern, content_text):
                    logger.warning(f"检测到不适宜儿童的内容: {pattern}")
                    return False
        elif target_age < 16:
            # 青少年内容：中等审查
            for i, pattern in enumerate(self.inappropriate_patterns):
                if i < 3 and re.search(pattern, content_text):  # 前三项对青少年更严格
                    logger.warning(f"检测到不适宜青少年的内容: {pattern}")
                    return False
        
        return True


class StoryCoherenceRule(Rule):
    """故事连贯性规则 - 确保剧情发展合理"""
    def __init__(self, description: str = "保证剧情发展的连贯性和逻辑性，避免突兀转折"):
        super().__init__("story_coherence", description, priority=80)
    
    def check(self, context: Dict[str, Any]) -> bool:
        """检查故事发展是否连贯"""
        self.last_checked = time.time()
        
        # 检查当前剧情转折是否合理
        current_twist = context.get("plot_twist", {})
        previous_state = context.get("previous_story_state", {})
        
        if current_twist:
            # 检查转折是否有伏笔支持
            has_foreshadowing = context.get("has_foreshadowing", False)
            if not has_foreshadowing:
                logger.warning("剧情转折缺乏伏笔，可能显得突兀")
                return False
            
            # 检查角色行为是否符合设定
            character_actions = context.get("character_actions", [])
            for action in character_actions:
                character_consistency = action.get("consistent_with_personality", True)
                if not character_consistency:
                    logger.warning(f"角色行为与设定不符: {action.get('character_name')}")
                    return False
        
        return True


class MysteryGameRuleEngine(RuleEngine):
    """悬疑游戏专用规则引擎"""
    def __init__(self, rules_config: Dict[str, str]):
        super().__init__(rules_config)
        self.logger = logging.getLogger("悬疑游戏规则引擎")
        # 添加游戏专用规则
        self._add_game_specific_rules()
    
    def _add_game_specific_rules(self):
        """添加游戏专用规则"""
        # 检查配置中是否包含游戏规则，如果没有则添加
        game_rules = {
            "immersion": "所有回复应保持游戏氛围，避免出戏内容",
            "difficulty_balance": "线索难度应循序渐进，避免过于简单或困难",
            "fair_play": "确保玩家可以通过合理推理找到真相，不设无解谜题",
            "age_appropriateness": "游戏内容应适合目标年龄段，避免过度恐怖或暴力",
            "story_coherence": "保证剧情发展的连贯性和逻辑性，避免突兀转折"
        }
        
        # 确保所有游戏规则都被加载
        for rule_name, description in game_rules.items():
            if rule_name not in self.rules_config:
                self.rules_config[rule_name] = description
        
        # 重新初始化规则列表
        self.rules.clear()
        self._initialize_rules()
    
    def _initialize_rules(self):
        """初始化规则列表，包括游戏专用规则"""
        # 创建规则实例
        rule_classes = {
            "confidentiality": self._get_parent_class("confidentiality"),
            "accuracy": self._get_parent_class("accuracy"),
            "responsiveness": self._get_parent_class("responsiveness"),
            "immersion": ImmersionRule,
            "difficulty_balance": DifficultyBalanceRule,
            "fair_play": FairPlayRule,
            "age_appropriateness": AgeAppropriatenessRule,
            "story_coherence": StoryCoherenceRule
        }
        
        # 加载配置的规则
        for rule_name, description in self.rules_config.items():
            if rule_name in rule_classes:
                rule_class = rule_classes[rule_name]
                self.rules.append(rule_class(description))
            else:
                # 对于未预定义的规则，创建通用规则
                self.rules.append(Rule(rule_name, description))
        
        # 按优先级排序（优先级高的先执行）
        self.rules.sort(key=lambda r: r.priority, reverse=True)
    
    def _get_parent_class(self, rule_name: str):
        """获取父类中的规则类"""
        # 从父类 RuleEngine 的初始化方法中获取规则类
        # 这里简化处理，直接返回通用 Rule 类
        return Rule
    
    def check_game_content(self, content_type: str, content_data: Dict[str, Any]) -> bool:
        """检查游戏内容是否符合所有规则"""
        # 根据内容类型构建检查上下文
        context = {
            "content_type": content_type,
            "timestamp": time.time(),
            "target_age": content_data.get("target_age", 16)
        }
        
        # 添加特定类型的内容
        if content_type == "dialogue":
            context["response_text"] = content_data.get("text", "")
            context["character_name"] = content_data.get("character", "")
        elif content_type == "clue":
            context["clue_difficulty"] = content_data.get("difficulty", 0.5)
            context["game_progress"] = content_data.get("game_progress", 0.0)
            context["content_text"] = content_data.get("description", "")
        elif content_type == "plot":
            context["plot_twist"] = content_data.get("twist", {})
            context["previous_story_state"] = content_data.get("previous_state", {})
            context["has_foreshadowing"] = content_data.get("has_foreshadowing", False)
            context["character_actions"] = content_data.get("character_actions", [])
        elif content_type == "puzzle":
            context["required_clues_for_solution"] = content_data.get("required_clues", [])
            context["available_clues_to_player"] = content_data.get("available_clues", [])
            context["misleading_clues"] = content_data.get("misleading_clues_count", 0)
        
        # 执行检查
        return self.check_rules(context)
    
    def get_game_specific_rules_status(self) -> Dict[str, Any]:
        """获取游戏特定规则的状态"""
        game_rules = [r for r in self.rules if r.name in [
            "immersion", "difficulty_balance", "fair_play", 
            "age_appropriateness", "story_coherence"
        ]]
        
        return {
            "game_rules_count": len(game_rules),
            "game_rules_details": [
                {
                    "name": r.name,
                    "description": r.description,
                    "priority": r.priority,
                    "last_checked": r.last_checked
                }
                for r in game_rules
            ]
        }


# 示例使用
def main():
    # 配置日志
    logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    
    # 创建游戏规则引擎
    rules_config = {
        "immersion": "所有回复应保持游戏氛围",
        "difficulty_balance": "线索难度应平衡",
        "fair_play": "确保游戏公平",
        "age_appropriateness": "内容适合16岁以上",
        "story_coherence": "保持故事连贯"
    }
    
    game_rule_engine = MysteryGameRuleEngine(rules_config)
    
    # 检查一些示例内容
    dialogue_content = {
        "text": "我是管家，请问您需要什么帮助？",
        "character": "管家",
        "target_age": 16
    }
    
    result = game_rule_engine.check_game_content("dialogue", dialogue_content)
    print(f"对话内容检查结果: {'通过' if result else '未通过'}")
    
    # 显示规则状态
    status = game_rule_engine.get_game_specific_rules_status()
    print(f"\n游戏规则状态:")
    for rule in status["game_rules_details"]:
        print(f"- {rule['name']} (优先级: {rule['priority']})")


if __name__ == "__main__":
    main()